<?php

    define("XML_NODE",  1);
    define("XML_LEAF",  2);
    define("XML_CLOSE", 3);
    define("XML_CDATA", 4);

    //basic xml document builder
    class CXmlBuilder
    {
		var $m_hNodes;
		var $m_iLvl;
		
		static function &GetInstance()
		{
			global $g_hObjects;
			static $m_hApp = NULL;
							
			if(!isset($m_hApp))
			{
				$m_hApp = new CXmlBuilder();
				$g_hObjects[] = $m_hApp;
				$m_hApp->OnInit();
			}
			
			return $m_hApp;
		}
		
		function OnInit()
		{	
			$this->m_hNodes = array();
		}
		
		function OnDestroy()
		{
		}
		
		//create new node
		function AddNode($szName,$szData = "",$bCloseLast = false)
		{	
			$szName = strval($szName);
			$szName = trim($szName);
			$szName = strip_tags($szName);
			$szName = htmlspecialchars($szName);
			
			$szData = strval($szData);
			$szData = trim($szData);
			$szData = strip_tags($szData);
			$szData = htmlspecialchars($szData);
		
			$this->m_hNodes[] = array('type' => XML_NODE, 'name' => $szName, 'data' => $szData);
		}
		
		//each node should be closed after creating
		function CloseNode($szName)
		{
			$this->m_hNodes[] = array('type' => XML_CLOSE, 'name' => $szName, 'data' => "");
		}
			
		//new leaf are automaticly closed
		function AddLeaf($szName,$szData = "")
		{
			$szName = strval($szName);
			$szName = trim($szName);
			$szName = strip_tags($szName);
			$szName = htmlspecialchars($szName);
			
			$szData = strval($szData);
			$szData = trim($szData);
			$szData = strip_tags($szData);
			$szData = htmlspecialchars($szData);
			
			$this->m_hNodes[] = array('type' => XML_LEAF, 'name' => $szName, 'data' => $szData);
		}
		
		//sometimes we need to add CDATA
		function AddCDATA($szData)
		{
			$this->m_hNodes[] = array('type' => XML_CDATA, 'name' => "", 'data' => $szData);
		}
			
		function ToXML()
		{
			$iCount = count($this->m_hNodes);
			
			$szXml  = '<?xml version="1.0" encoding="utf-8"?>';
			
			for($i=0;$i<$iCount;$i++)
			{
				if($this->m_hNodes[$i]['type'] == XML_NODE)
				{
					$szXml .= '<'.$this->m_hNodes[$i]['name'].'>';
					
					if( isset($this->m_hNodes[$i+1]) && $this->m_hNodes[$i+1]['type'] == XML_CDATA )
					{
						$szXml .= '<![CDATA['.$this->m_hNodes[$i+1]['data'].']]>';
					}
					else
					{
						$szXml .= $this->m_hNodes[$i]['data'];
					}
				}
				else if($this->m_hNodes[$i]['type'] == XML_CLOSE)
				{
					$szXml .= '</'.$this->m_hNodes[$i]['name'].'>';
				}
				else if($this->m_hNodes[$i]['type'] == XML_LEAF)
				{
					$szXml .= '<'.$this->m_hNodes[$i]['name'].'>';
					
					if( isset($this->m_hNodes[$i+1]) && $this->m_hNodes[$i+1]['type'] == XML_CDATA )
					{
						$szXml .= '<![CDATA['.$this->m_hNodes[$i+1]['data'].']]>';
					}
					else
					{
						$szXml .= $this->m_hNodes[$i]['data'];
					}
					
					$szXml .= '</'.$this->m_hNodes[$i]['name'].'>';
				}
			}
			
			return $szXml;
		}
    }

?>